package org.cypress.rtpack.service;

import org.cypress.rtpack.VO.SoePt;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.GZIPInputStream;

public class PtFileHelper {
    public static List<SoePt> getPtList(String fileName) {
        List<SoePt> pointList = new ArrayList<>();
        try {
            // 步骤1: 读取文件原始字节数据
            byte[] fileData = loadFromFile(fileName);
            System.out.println("文件大小: " + fileData.length + " 字节");

            // 步骤2: 验证数据完整性 (MD5校验)
            if (validateData(fileData)) {
                System.out.println("MD5校验通过，数据完整");

                // 步骤3: 移除MD5头信息
                byte[] dataWithoutMD5 = removeMD5ValueFromHeader(fileData);
                System.out.println("移除MD5头后大小: " + dataWithoutMD5.length + " 字节");

                // 步骤4: 解压缩数据
                byte[] decompressedData = decompress(dataWithoutMD5);
                System.out.println("解压后大小: " + decompressedData.length + " 字节");

                // 步骤5: 将字节数据转换为字符串并逐行解析
                String content = new String(decompressedData, StandardCharsets.UTF_8);
                System.out.println("文件内容:");
                System.out.println("====================");


                String[] lines = content.split("\n");

                for (String line : lines) {
                    if (line.trim().isEmpty()) continue;
                    System.out.println("原始行: " + line);
                    // 解析每行数据
                    SoePt point = parseLine(line);
                    if (point != null) {
                        pointList.add(point);
                        System.out.println("解析成功: " + point.getChannelName());
                    }
                }

                System.out.println("====================");
                System.out.println("总共解析了 " + pointList.size() + " 个点表项");

                // 显示解析结果
                for (SoePt point : pointList) {
                    System.out.println(point.toString());
                }

            } else {
                System.out.println("MD5校验失败，数据可能已损坏");
            }
        } catch (Exception e) {
            System.out.println("读取文件时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
        return pointList;
    }

    // 读取文件字节数据
    public static byte[] loadFromFile(String fileName) throws IOException {
        if (fileName == null || fileName.isEmpty()) {
            throw new IllegalArgumentException("文件名无效");
        }

        File file = new File(fileName);
        if (!file.exists()) {
            throw new FileNotFoundException("文件不存在: " + fileName);
        }

        try (FileInputStream fis = new FileInputStream(file);
             ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {

            byte[] tmp = new byte[4096];
            int bytesRead;
            while ((bytesRead = fis.read(tmp)) != -1) {
                buffer.write(tmp, 0, bytesRead);
            }

            return buffer.toByteArray();
        }
    }

    // 验证MD5数据完整性
    public static boolean validateData(byte[] data) throws NoSuchAlgorithmException {
        if (data == null) {
            throw new IllegalArgumentException("数据为空");
        }
        if (data.length < 16) {
            throw new IllegalArgumentException("数据长度不足");
        }

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte[] result = md5.digest(Arrays.copyOfRange(data, 16, data.length));

        for (int i = 0; i < 16; i++) {
            if (result[i] != data[i]) {
                return false;
            }
        }
        return true;
    }

    // 移除MD5头信息
    public static byte[] removeMD5ValueFromHeader(byte[] data) {
        if (data == null) {
            throw new IllegalArgumentException("数据为空");
        }
        if (data.length < 16) {
            throw new IllegalArgumentException("数据长度不足");
        }

        byte[] result = new byte[data.length - 16];
        System.arraycopy(data, 16, result, 0, result.length);
        return result;
    }

    // 解压缩数据
    public static byte[] decompress(byte[] data) throws IOException {
        if (data == null) {
            throw new IllegalArgumentException("数据为空");
        }

        try (ByteArrayInputStream buffer = new ByteArrayInputStream(data);
             GZIPInputStream gzip = new GZIPInputStream(buffer);
             ByteArrayOutputStream resultBuffer = new ByteArrayOutputStream()) {

            byte[] tmp = new byte[4096];
            int bytesRead;
            while ((bytesRead = gzip.read(tmp)) != -1) {
                resultBuffer.write(tmp, 0, bytesRead);
            }

            return resultBuffer.toByteArray();
        }
    }

    // 解析单行数据
    public static SoePt parseLine(String line) {
        if (line == null || line.trim().isEmpty()) {
            return null;
        }

        String[] parts = line.split(",");
        if (parts.length != 7) {
            System.out.println("格式错误，跳过行: " + line);
            return null;
        }

        try {
            SoePt point = new SoePt();

            // SOEID
            point.setSoeId(Integer.parseInt(parts[0].trim()));

            // SoeEnabled
            point.setSoeEnabled(parseBoolean(parts[1].trim()));

            // 其他字段
            point.setChannelName(parts[2].trim());
            point.setChannelAlias(parts[3].trim());
            point.setTagName("");
            point.setState0Alias(parts[4].trim());
            point.setState1Alias(parts[5].trim());
            point.setDescription(parts[6].trim());

            return point;

        } catch (NumberFormatException e) {
            System.out.println("数字格式错误，跳过行: " + line);
            return null;
        } catch (Exception e) {
            System.out.println("解析错误，跳过行: " + line);
            return null;
        }
    }

    // 解析布尔值
    public static boolean parseBoolean(String value) {
        if (value == null) return false;

        if (value.equalsIgnoreCase("true")) return true;
        if (value.equalsIgnoreCase("false")) return false;
        if (value.equals("1")) return true;
        if (value.equals("0")) return false;

        return Boolean.parseBoolean(value);
    }
}
